package com.iterator.service.wechat.tcy;

import com.iterator.bean.web.pojo.tcy.*;
import com.iterator.bean.wechat.tcy.*;
import com.iterator.bean.wechat.tcy.pojo.*;

import com.iterator.mapper.web.goodsManager.GoodsMapper;
import com.iterator.mapper.web.goodsManager.GoodsProductMapper;
import com.iterator.mapper.wechat.lyh.WxUserMapper;
import com.iterator.mapper.wechat.tcy.*;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author tean_cy
 * @date 2021/1/12 17:24
 */

@Service
public class CartServiceImpl implements CartService {
    @Autowired
    MyCartMapper myCartMapper;

    @Autowired
    GoodsMapper goodsMapper;

    @Autowired
    GoodsProductMapper goodsProductMapper;

    @Autowired
    CartAddressMapper addressMapper;

    @Autowired
    CartCouponMapper cartCouponMapper;

    @Autowired
    CartCouponUserMapper cartCouponUserMapper;

    @Autowired
    WxUserMapper wxUserMapper;

    @Autowired
    MallSystemMapper mallSystemMapper;

    @Override
    public CartIndexVO index() {
        String username = (String) SecurityUtils.getSubject().getPrincipal();
        Integer userId = wxUserMapper.selectUserIdByName(username);

        MyCartExample myCartExample = new MyCartExample();
        MyCartExample.Criteria criteria = myCartExample.createCriteria();
        criteria.andUserIdEqualTo(userId);
        criteria.andDeletedEqualTo(true);
        List<MyCart> myCarts = myCartMapper.selectByExample(myCartExample);

        // 获取订单总数
        long goodsCount = 0;
        // 获取被选中的商品
        long checkedGoodsCount = 0;
        // 获取选中的商品的总价
        double checkedGoodsAmount = 0;
        // 获取商品总价
        double goodsAmount = 0;

        for (MyCart cart : myCarts) {
            goodsCount += cart.getNumber();
            if (cart.getChecked()) {
                checkedGoodsCount += cart.getNumber();
                checkedGoodsAmount += (cart.getPrice().doubleValue() * cart.getNumber());
            }
            goodsAmount += (cart.getPrice().doubleValue() * cart.getNumber());
        }

        // 封装cartTotal
        CartTotal cartTotal = new CartTotal(goodsCount, checkedGoodsCount, goodsAmount, checkedGoodsAmount);
        // 将响应结果封装进响应体
        CartIndexVO cartIndexVO = new CartIndexVO(cartTotal, myCarts);
        return cartIndexVO;
    }

    @Override
    public int add(Integer goodsId, Integer number, Integer productId) {

        String username = (String) SecurityUtils.getSubject().getPrincipal();
        Integer userId = wxUserMapper.selectUserIdByName(username);

        // 根据goodsId获取good的相关信息，然后将其添加到cart表中
        // 连表查询product表获取相关信息

        //查询goods表
        Goods goods = goodsMapper.selectByPrimaryKey(goodsId);

        //查询product表
        GoodsProduct product = goodsProductMapper.selectByPrimaryKey(productId);
        List<String> specifications = product.getSpecifications();

        Date date = new Date();
        MyCart myCart = new MyCart(null, userId, goodsId, goods.getGoodsSn(), goods.getName(),
                productId, goods.getRetailPrice(), number, specifications,
                false, goods.getPicUrl(), date, date, true);

        // 购物车合并：如果同一件商品同一规格，多次添加，修改 number即可，
        // 因此添加之前需要判断是否有该商品存在于购物车
        MyCartExample cartExample = new MyCartExample();
        MyCartExample.Criteria criteria = cartExample.createCriteria();
        criteria.andUserIdEqualTo(userId);
        criteria.andGoodsIdEqualTo(goodsId);
        criteria.andProductIdEqualTo(productId);
        criteria.andDeletedEqualTo(true);
        // 添加商品的specification参数只能是单个，直接取用
        // criteria.andSpecificationsEqualTo(specifications.get(0));
        List<MyCart> myCarts = myCartMapper.selectByExample(cartExample);

        if (myCarts.size() != 0) {
            // 说明购物车已经存在该商品，直接update
            MyCartExample cartExample2 = new MyCartExample();
            MyCartExample.Criteria criteria1 = cartExample2.createCriteria();
            MyCart cart = new MyCart();
            // short类型运算 增加一个临时变量接收，才能计算成功
            cart.setNumber(myCarts.get(0).getNumber()+ number);
            cart.setChecked(true);
            criteria1.andUserIdEqualTo(userId);
            criteria1.andGoodsIdEqualTo(goodsId);
            criteria1.andProductIdEqualTo(productId);
            int update = myCartMapper.updateByExampleSelective(cart, cartExample2);
            int code = -1;
            if (update != 0) {
                code = myCartMapper.selectCountByUserId(userId, true);
            }
            return code;
        }

        int insert = myCartMapper.insert(myCart);

        int code = -1;
        if (insert != 0) {
            // 表示加入购入车成功，然后根据userId 查出所有订单
            code = myCartMapper.selectCountByUserId(userId, true);
        }
        return code;
    }

    @Override
    public int update(Integer goodsId, Integer id, Integer number, Integer productId) {
        String username = (String) SecurityUtils.getSubject().getPrincipal();
        Integer userId = wxUserMapper.selectUserIdByName(username);

        // 更新购物车，目前可更新的只有数量,根据拿到number去修改数据库
        MyCart myCart = myCartMapper.selectByPrimaryKey(id);
        myCart.setNumber(number);

        int update = myCartMapper.updateByPrimaryKey(myCart);

        return update;
    }

    @Override
    public CartIndexVO delete(List<Integer> productIds) {
        String username = (String) SecurityUtils.getSubject().getPrincipal();
        Integer userId = wxUserMapper.selectUserIdByName(username);

        // 根据productId userId 从cart表中删除该数据(逻辑删除)
        int delete = -1;
        for (Integer productId : productIds) {
            MyCartExample myCartExample = new MyCartExample();
            MyCartExample.Criteria criteria = myCartExample.createCriteria();
            MyCart myCart = new MyCart();
            myCart.setDeleted(false);
            criteria.andUserIdEqualTo(userId);
            criteria.andProductIdEqualTo(productId);
            delete = myCartMapper.updateByExampleSelective(myCart, myCartExample);
            if (delete == 0) {
                return null;
            }
        }
        // 执行到这一步表示都删除成功,将结果返回
        CartTotal cartTotal = new CartTotal(0, 0, 0.0, 0.0);
        return new CartIndexVO(cartTotal, null);
    }

    @Override
    public int goodsCount() {
        String username = (String) SecurityUtils.getSubject().getPrincipal();
        Integer userId = wxUserMapper.selectUserIdByName(username);

        // 根据userId获取到购物车的商品数量
        MyCartExample myCartExample = new MyCartExample();
        MyCartExample.Criteria criteria = myCartExample.createCriteria();
        criteria.andUserIdEqualTo(userId);
        criteria.andDeletedEqualTo(true);
        List<MyCart> myCart = myCartMapper.selectByExample(myCartExample);
        int date = 0;
        for (MyCart cart : myCart) {
            date += cart.getNumber();
        }
        return date;
    }

    @Override
    public CartIndexVO checked(CheckedBO checkedBO) {
        String username = (String) SecurityUtils.getSubject().getPrincipal();
        Integer userId = wxUserMapper.selectUserIdByName(username);

        // 修改isChecked的状态，1为选中，0为未被选中
        List<Integer> productIds = checkedBO.getProductIds();

        // 将更新更新内容放入myCart
        MyCart myCart = new MyCart();
        myCart.setChecked(checkedBO.getIsChecked());

        // 单个选中的逻辑
        if (productIds.size() == 1) {
            MyCartExample myCartExample = new MyCartExample();
            MyCartExample.Criteria criteria = myCartExample.createCriteria();
            criteria.andUserIdEqualTo(userId);
            criteria.andDeletedEqualTo(true);

            criteria.andProductIdEqualTo(productIds.get(0));
            int update = myCartMapper.updateByExampleSelective(myCart, myCartExample);
            if (update == 0) {
                return null;
            }
        } else {
            // 考虑到是全选的情况，用list接收id ，然后遍历，其中如果表中的checked的状态和传入的一致，则不需要修改
            for (Integer productId : productIds) {
                // 查询出checked
                Boolean checked = myCartMapper.selectChecked(productId, userId);
                if (checked != checkedBO.getIsChecked()) {
                    MyCartExample myCartExample = new MyCartExample();
                    MyCartExample.Criteria criteria = myCartExample.createCriteria();
                    // 拼接查询条件，根据UserId和productId来修改checked
                    criteria.andUserIdEqualTo(userId);
                    criteria.andProductIdEqualTo(productId);
                    criteria.andDeletedEqualTo(true);
                    int update = myCartMapper.updateByExampleSelective(myCart, myCartExample);
                    if (update == 0) {
                        return null;
                    }
                }
            }
        }

        // 查询结果回显 不过是选中几个 回显的都是购物车的全部商品
        MyCartExample cartExample = new MyCartExample();
        MyCartExample.Criteria criteria1 = cartExample.createCriteria();
        criteria1.andUserIdEqualTo(userId);
        criteria1.andDeletedEqualTo(true);

        List<MyCart> myCarts = myCartMapper.selectByExample(cartExample);

        // 获取订单总数
        long goodsCount = 0;
        // 获取被选中的商品
        long checkedGoodsCount = 0;
        // 获取选中的商品的总价
        double checkedGoodsAmount = 0;
        // 获取商品总价
        double goodsAmount = 0;

        for (MyCart cart : myCarts) {
            goodsCount += cart.getNumber();
            if (cart.getChecked()) {
                checkedGoodsCount += cart.getNumber();
                checkedGoodsAmount += (cart.getPrice().doubleValue() * cart.getNumber());
            }
            goodsAmount += (cart.getPrice().doubleValue() * cart.getNumber());
        }

        // 封装cartTotal
        CartTotal cartTotal = new CartTotal(goodsCount, checkedGoodsCount, goodsAmount, checkedGoodsAmount);
        // 将响应结果封装进响应体
        CartIndexVO cartIndexVO = new CartIndexVO(cartTotal, myCarts);
        return cartIndexVO;
    }

    @Override
    public int fastAdd(Integer goodsId, Integer number, Integer productId) {
        String username = (String) SecurityUtils.getSubject().getPrincipal();
        Integer userId = wxUserMapper.selectUserIdByName(username);

        // 根据goodId和productId查到相应的商品信息，然后封装到Cart表
        // 根据userId 添加到相应的表中

        //查询goods表
        Goods goods = goodsMapper.selectByPrimaryKey(goodsId);

        //查询product表
        GoodsProduct product = goodsProductMapper.selectByPrimaryKey(productId);
        List<String> specifications = product.getSpecifications();

        Date date = new Date();
        MyCart myCart = new MyCart(null, userId, goodsId, goods.getGoodsSn(), goods.getName(),
                productId, goods.getRetailPrice(), number, specifications,
                false, goods.getPicUrl(), date, date, true);

        // 购物车合并：如果同一件商品同一规格，多次添加，覆盖之前的数据，
        // 因此添加之前需要判断是否有该商品存在于购物车
        MyCartExample cartExample = new MyCartExample();
        MyCartExample.Criteria criteria = cartExample.createCriteria();
        criteria.andUserIdEqualTo(userId);
        criteria.andGoodsIdEqualTo(goodsId);
        criteria.andProductIdEqualTo(productId);
        criteria.andDeletedEqualTo(true);
        // 添加商品的specification参数只能是单个，直接取用
        // criteria.andSpecificationsEqualTo(specifications.get(0));
        List<MyCart> myCarts = myCartMapper.selectByExample(cartExample);

        if (myCarts.size() != 0) {
            // 说明购物车已经存在该商品，直接update
            MyCartExample cartExample2 = new MyCartExample();
            MyCartExample.Criteria criteria1 = cartExample2.createCriteria();
            MyCart cart = new MyCart();
            cart.setNumber(number);
            criteria1.andUserIdEqualTo(userId);
            criteria1.andGoodsIdEqualTo(goodsId);
            criteria1.andProductIdEqualTo(productId);
            int update = myCartMapper.updateByExampleSelective(cart, cartExample2);
            int cartId = -1;
            if (update != 0) {
                cartId = myCarts.get(0).getId();
            }
            return cartId;
        }

        int insert = myCartMapper.insert(myCart);
        return myCart.getId();
    }

    @Override
    public CartCheckOutVO checkout(Integer cartId, Integer addressId, Integer couponId, Integer grouponRulesId) {
        String username = (String) SecurityUtils.getSubject().getPrincipal();
        Integer userId = wxUserMapper.selectUserIdByName(username);

        // 根据checkedId查出checkedGoodsList
        MyCartExample cartExample = new MyCartExample();
        MyCartExample.Criteria criteria2 = cartExample.createCriteria();
        // 判断cartId的值

        List<MyCart> myCart = new ArrayList<>();
        Boolean checkId;
        if (cartId == 0 || cartId == 1){
            checkId = true;
        Boolean deleteId = true;
        // 从数据库拿到要下单的商品
         myCart = myCartMapper.selectByUseIdAndCheckId(userId,checkId,deleteId);
        }else {
              MyCart cart = myCartMapper.selectByPrimaryKey(cartId);
              myCart.add(cart);
        }

        // 拿到收货地址信息
        CartAddress checkAddress = addressMapper.selectByPrimaryKey(addressId);

        // 通过userId查询出conpon-user中是否有优惠券，拿到优惠券的id，然后根据conponId查询出优惠券
        List<Integer> couponIds = cartCouponUserMapper.selectByCouponIdByUserId(userId);
        // 团购不考虑，直接封装0
        BigDecimal couponPrice = new BigDecimal(0);
        Integer availableCouponLength = 0;
        BigDecimal actualPrice = new BigDecimal(0);
        BigDecimal goodsTotalPrice = new BigDecimal(0);

        // 如果没有优惠券，金额都是原价 单价 * 件数
        for (MyCart cart : myCart) {
            BigDecimal number = new BigDecimal(cart.getNumber());
            BigDecimal aaa  = cart.getPrice().multiply(number);
            // 多件商品的原价合计
            goodsTotalPrice = goodsTotalPrice.add(aaa);
        }
        actualPrice = goodsTotalPrice;
        // 优惠券的张数
        availableCouponLength = couponIds.size();
        // 说明找到了合适的优惠券，进入去做优惠运算
        if (couponIds.size() != 0) {
            for (Integer id : couponIds) {
                // 证明该用户有优惠券，去查优惠券表，判断是否有符合规则的优惠券
                CartCouponExample cartCouponExample = new CartCouponExample();
                CartCouponExample.Criteria criteria = cartCouponExample.createCriteria();
                // 通过优惠券的id及使用的金额，status = false
                criteria.andIdEqualTo(id);
                Short a = 0;
                criteria.andStatusEqualTo(a);
                // 商品的实际价格价格要大于等于优惠券最小的使用权限
                criteria.andMinLessThanOrEqualTo(actualPrice);
                List<CartCoupon> cartCoupons = cartCouponMapper.selectByExample(cartCouponExample);
                for (CartCoupon cartCoupon : cartCoupons) {
                    if (cartCoupon.getId() == couponId) {
                        // 单件商品优化后的价格 原价减去折扣价
                        actualPrice = actualPrice.subtract(cartCoupon.getDiscount());
                        // 优惠金额
                        couponPrice = cartCoupon.getDiscount();
                    }
                }
            }
        }


        // TODO 对运费的计算
        // 拿到最少需要消费的金额  以及邮费
        String name1 = "cskaoyan_mall_express_freight_min";
        String name2 = "cskaoyan_mall_express_freight_value";
        BigDecimal monetary = mallSystemMapper.selectMonetary(name1);
        BigDecimal freightPrice = mallSystemMapper.selectFreightPrice(name2);
        actualPrice = actualPrice.add(freightPrice);

        // 此时的运费是需要的，但是如果满足条件进入以下逻辑
        if (actualPrice.compareTo(monetary) > -1) {
            // 总价格减去运费 然后将运费置为0
            BigDecimal subtract = actualPrice.subtract(freightPrice);
            freightPrice = new BigDecimal(0);
            actualPrice = subtract;
        }
        // 订单总价格 ：优惠券和折扣后的
        BigDecimal orderTotalPrice = actualPrice;
        CartCheckOutVO cartCheckOutVO = new CartCheckOutVO();
        cartCheckOutVO.setGrouponPrice(0);
        cartCheckOutVO.setGrouponRulesId(0);
        cartCheckOutVO.setCheckedAddress(checkAddress);
        cartCheckOutVO.setActualPrice(actualPrice);
        cartCheckOutVO.setOrderTotalPrice(orderTotalPrice);
        cartCheckOutVO.setCouponPrice(couponPrice);
        cartCheckOutVO.setAvailableCouponLength(availableCouponLength);
        cartCheckOutVO.setCouponId(couponId);
        cartCheckOutVO.setFreightPrice(freightPrice);
        cartCheckOutVO.setCheckedGoodsList(myCart);
        cartCheckOutVO.setGoodsTotalPrice(goodsTotalPrice);
        cartCheckOutVO.setAddressId(addressId);

        return cartCheckOutVO;
    }
}
